package net.sf.jOpinionPoll.security;

import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import java.util.regex.Pattern;

import net.sf.jOpinionPoll.entity.Conteudo;
import net.sf.jOpinionPoll.entity.Papel;
import net.sf.jOpinionPoll.facade.UsuarioFacade;

import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.ConfigAttributeEditor;
import org.acegisecurity.intercept.web.AbstractFilterInvocationDefinitionSource;

public class JOpinionPollFilterInvocationDefinitionSource extends AbstractFilterInvocationDefinitionSource {
	private static final Logger m_Logger = Logger.getLogger(JOpinionPollFilterInvocationDefinitionSource.class);
	
	private UsuarioFacade m_UsuarioFacade;
	private PadraoDeConteudo[] m_PadraoDeConteudo;
	
	/* Injetado IOC */
	public void setUsuarioFacade(UsuarioFacade usuarioFacade) {
		m_UsuarioFacade = usuarioFacade;
	}
	
	@Override
	public ConfigAttributeDefinition lookupAttributes(String url) {
		if (m_PadraoDeConteudo == null) {
			m_Logger.info("Inicializando filtro de acesso a objetos...");

			List<Conteudo> conteudos = m_UsuarioFacade.listConteudo();
			
			m_PadraoDeConteudo = new PadraoDeConteudo[conteudos.size()];
			
			for(int i = 0; i < conteudos.size(); i++) {
				try {
					m_PadraoDeConteudo[i] = new PadraoDeConteudo(
							Pattern.compile(conteudos.get(i).getNome()), conteudos.get(i));
				}
				catch (Exception ex) {
					m_Logger.error("Erro ao compilar padrao " + conteudos.get(i).getNome());
					ex.printStackTrace();
				}
			}
			
			m_Logger.info("Filtro inicializado com sucesso!");
		}
	
	    ConfigAttributeEditor configAttrEditor;
		Conteudo ctd;
		StringBuilder sb;
		ConfigAttributeDefinition configAttrDef;
		
		for (int i = 0; i < m_PadraoDeConteudo.length; i++) {
			if (m_PadraoDeConteudo[i].getPattern().matcher(url).matches()) {
				sb = new StringBuilder();
				ctd = m_PadraoDeConteudo[i].getConteudo();
				
				for (Papel papel : ctd.getPapeis()) {
					sb.append(papel.getTipoDePapel());
					sb.append(',');
				}
				
				sb.deleteCharAt(sb.length() - 1);
				
				configAttrEditor = new ConfigAttributeEditor();
				configAttrEditor.setAsText(sb.toString());
				configAttrDef = (ConfigAttributeDefinition)configAttrEditor.getValue();

				return configAttrDef;
			}
		}
		
		throw new PapelNaoEncontradoException("Papel nao encontrado para o recurso " + url);
	}

	@Override
	@SuppressWarnings("unchecked")
	public Iterator getConfigAttributeDefinitions() {
		return null;
	}
	
	private class PadraoDeConteudo {
		private Pattern m_Pattern;
		private Conteudo m_Conteudo;
		
		public PadraoDeConteudo (Pattern p, Conteudo c) {
			setPattern(p);
			setConteudo(c);
		}
		
		public Pattern getPattern() {
			return m_Pattern;
		}
		
		public void setPattern(Pattern pattern) {
			this.m_Pattern = pattern;
		}
		
		public Conteudo getConteudo() {
			return m_Conteudo;
		}
		
		public void setConteudo(Conteudo conteudo) {
			this.m_Conteudo = conteudo;
		}
	}
}
